(* parser.ml - .obj parser
 * Licence: LGPLv3
 * Authors: Franck "kushou" Michea < michea_f@epita.fr >
 *)

let obj2triangles path =
  let path = path ^ ".obj" in
  let iof = int_of_float in
  let points = Hashtbl.create 1000001 in
  let obj = ref [[]] in
  let new_obj () = obj := [] :: !obj in
  let push_obj tr =
    obj := (tr :: List.hd !obj) :: (List.tl !obj) in
  let reg_point l x_ y_ z_ =
    Hashtbl.add points l (new Point.point (iof x_,iof y_,iof z_)) in
  let add_triangle p1 p2 p3 =
    let t = new Triangle.triangle 
      (Hashtbl.find points p1)
      (Hashtbl.find points p2)
      (Hashtbl.find points p3)
    in push_obj t in
  let file = open_in path in
  let l = ref 0 and line = ref "" in
  while (try begin line := input_line file; true end with End_of_file -> false)
  do begin
    if String.length !line < 2 then ()
    else
      match String.sub !line 0 2 with
	  "g " -> new_obj ()
	| "v " -> begin
	  l := !l + 1;
	  Scanf.sscanf !line "v %f %f %f" (reg_point !l) end
	| "f " ->
	  Scanf.sscanf !line "f %d// %d// %d//" add_triangle
	| _ -> ()
  end done; close_in file; !obj

let gen_obj_ img step =
  let foi = float_of_int in
  let lines = Hashtbl.create 1001 in
  let points = Triangle.pointlist step img in
  let triangles = Triangle.trilist step img in
  let base_str = "# Generated by FearOfTheMap\n\n" in
  let l = ref 1 in
  let fpoints acc x = begin
    Hashtbl.add lines x#str_coord !l;
    l := !l + 1;
    Printf.sprintf "%sv %f %f %f\n" acc (foi x#get_x)
      (foi x#get_y) (foi x#get_z) end in
  let obj_points =
    let a = List.fold_left fpoints base_str points
    in Printf.sprintf "%s\n\n" a in
  let ftri acc x =
    Printf.sprintf "%sf %d// %d// %d//\n" acc
      (try Hashtbl.find lines x#s1#str_coord with Not_found -> 1)
      (try Hashtbl.find lines x#s2#str_coord with Not_found -> 1)
      (try Hashtbl.find lines x#s3#str_coord with Not_found -> 1) in
  let tri_obj =
    List.fold_left ftri obj_points triangles in
  let file = open_out img#obj_filename in begin
    output_string file tri_obj;
    close_out file;
    print_endline "File *.obj generated successfully!" end

let gen_obj img =
  gen_obj_ img (Io.get_step ())

let parse_heights path =
  let path = path ^ ".heights.txt" in
  let hcolors = ref [] and line = ref "" in
  let file = open_in path in
  let update_h  h r g b =  hcolors := (h, (r,g,b)) :: !hcolors in
  while (try begin line := input_line file; true end with End_of_file -> false)
  do
    Scanf.sscanf !line "%d: %d %d %d" update_h
  done;
  close_in file;
  !hcolors
